home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / macros / latex209 / contrib / textyl / src / spline.c < prev    next >
C/C++ Source or Header  |  1993-11-07  |  16KB  |  661 lines

  1. #include    "defs.h"
  2. #include    "globals.h"
  3. #include    "tables.h"
  4.  
  5. /* &&Module spline.p */
  6. /*
  7.  * Procedures below may make free use of the global variables arrayXY   [list of control points] pointmatrix [list of spline
  8.  * segments] knot    [list of spline knots] catrommtx  [matrix for Catmull-Rom splines] bsplmtx   [matrix for B-splines]
  9.  * lastPoint, intervals
  10.  */
  11.  
  12.  
  13. /*-----------------------------------------------------*/
  14. int 
  15. max(a, b)
  16.     int             a, b;
  17. {
  18.     if (a > b)
  19.         return a;
  20.     else
  21.         return b;
  22. }
  23.  
  24.  
  25. /*-----------------------------------------------------*/
  26. int 
  27. min(a, b)
  28.     int             a, b;
  29. {
  30.     if (a < b)
  31.         return a;
  32.     else
  33.         return b;
  34. }
  35.  
  36. /*-----------------------------------------------------*/
  37. static void 
  38. matXvector(m, v, result)
  39.     double          (*m)[4];
  40.     double         *v, *result;
  41. {
  42.     /* IN */
  43.     /* IN */
  44.     /* OUT */
  45.     double          t[4];
  46.  
  47.     t[0] = v[0] * m[0][0] + v[1] * m[0][1] + v[2] * m[0][2] + v[3] * m[0][3];
  48.     t[1] = v[0] * m[1][0] + v[1] * m[1][1] + v[2] * m[1][2] + v[3] * m[1][3];
  49.     t[2] = v[0] * m[2][0] + v[1] * m[2][1] + v[2] * m[2][2] + v[3] * m[2][3];
  50.     t[3] = v[0] * m[3][0] + v[1] * m[3][1] + v[2] * m[3][2] + v[3] * m[3][3];
  51.     result[0] = t[0];
  52.     result[1] = t[1];
  53.     result[2] = t[2];
  54.     result[3] = t[3];
  55. }
  56.  
  57.  
  58. /*-----------------------------------------------------*/
  59. /* actually the dot-product */
  60. static double 
  61. vecXvec(v1, v2)
  62.     double         *v1, *v2;
  63. {
  64.     return (v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2] + v1[3] * v2[3]);
  65. }
  66.  
  67.  
  68. /*------------------------------------------------------*/
  69. /* basXctl is the pre-computed BasisMatrix times the control-point vector */
  70.  
  71. static double 
  72. splinePosition(basXctl, t)
  73.     double         *basXctl;
  74.     double          t;
  75. {
  76.     /* IN */
  77.     double          tvect[4];    /* vector of t values for spline matrix */
  78.  
  79.     tvect[3] = 1.0;
  80.     tvect[2] = t;
  81.     tvect[1] = t * t;
  82.     if (tvect[1] <= MINREAL)/* avoid underflow problems */
  83.         tvect[1] = 0.0;
  84.     tvect[0] = t * tvect[1];/* t^3 */
  85.     return (vecXvec(tvect, basXctl));
  86. }
  87.  
  88.  
  89. /*-------------------------------------------------*/
  90. static int 
  91. TwoToThe(n)
  92.     int             n;
  93. {
  94.     int             i, tmp;
  95.  
  96.     for (i = 0, tmp = 1; i < n; i++)
  97.         tmp *= 2;
  98.     return (tmp);
  99. }
  100.  
  101. /*------------------------------------------------------*/
  102. double 
  103. distance(x0, y0, x1, y1)
  104.     double          x0, y0, x1, y1;
  105. {
  106.     return (sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)));
  107. }
  108.  
  109.  
  110. /*------------------------------------------------------*/
  111. /*
  112.  * compute the number of subdivisions for this span. We do this by a quadrature method and a simple linear-distance metric.
  113.  * This is not optimal in the number of subdivisions actually required, but is computationally efficient and accurate to the
  114.  * nearest power of 2 .
  115.  */
  116. static int32 
  117. numsubdivisions(XtimesBas, YtimesBas, resolution)
  118.     double         *XtimesBas, *YtimesBas;
  119.     int32           resolution;
  120. {
  121.     int32           n;
  122.     double          t, x0, y0, xt, yt;
  123.  
  124.     x0 = splinePosition(XtimesBas, 0.0);
  125.     y0 = splinePosition(YtimesBas, 0.0);
  126.  
  127.     t = 1.0;
  128.     n = 0;
  129.     xt = splinePosition(XtimesBas, t);
  130.     yt = splinePosition(YtimesBas, t);
  131.  
  132.     while ((int32) floor(distance(x0, y0, xt, yt) + 0.5) > resolution || n < 1)
  133.     {
  134.         t /= 2.0;    /* perform the quadrature */
  135.         n++;
  136.         xt = splinePosition(XtimesBas, t);
  137.         yt = splinePosition(YtimesBas, t);
  138.     }            /* while */
  139.     return (TwoToThe(n));
  140. }
  141.  
  142.  
  143. /*------------------------------------------------------------------------*/
  144. /*
  145.  * compute new control vertices such that the resulting spline will interpolate through the old control points. This will work
  146.  * as int32 as the actual arc length between consecutive nodes does not vary from span to span. The method is noted in Wu and
  147.  * Abel's CACM 20(10) Oct 77 paper but the actual working method is from Barsky and Greenberg's paper in CG&IP 14(3) Nov 1980
  148.  * pp.203-226
  149.  */
  150. static void 
  151. invertsplvertices(numpts, isclosed, xys)
  152.     int32           numpts;
  153.     int        isclosed;
  154. int32(*xys)[2];
  155. {
  156.     /* INOUT */
  157.     int32           i;
  158.     double          beta[MAXCTLPTS + 1], Xrprime[MAXCTLPTS + 1], Yrprime[MAXCTLPTS + 1];
  159.     ControlPoints   tempxys;
  160.  
  161.     /* compute the values of beta */
  162.     beta[1] = 0.25;
  163.     for (i = 2; i <= numpts + 1; i++)
  164.         beta[i] = 1.0 / (4.0 - beta[i - 1]);
  165.  
  166.     /* and the r primes from the original vertices */
  167.     Xrprime[1] = beta[1] * xys[1][0] * 5.0;
  168.     Yrprime[1] = beta[1] * xys[1][1] * 5.0;
  169.     for (i = 2; i < numpts; i++)
  170.     {
  171.         Xrprime[i] = beta[i] * (6.0 * xys[i][0] - Xrprime[i - 1]);
  172.         Yrprime[i] = beta[i] * (6.0 * xys[i][1] - Yrprime[i - 1]);
  173.     }            /* for */
  174.     Xrprime[numpts] = beta[numpts] * (5.0 * xys[numpts][0] - Xrprime[numpts - 1]);
  175.     Yrprime[numpts] = beta[numpts] * (5.0 * xys[numpts][1] - Yrprime[numpts - 1]);
  176.  
  177.     /* Now perform the back-substitution from the bottom up */
  178.     tempxys[numpts][0] = (int32) floor(Xrprime[numpts] + 0.5);
  179.     tempxys[numpts][1] = (int32) floor(Yrprime[numpts] + 0.5);
  180.     for (i = numpts - 1; i >= 1; i--)
  181.     {
  182.         tempxys[i]
  183.             [0] = (int32) floor(Xrprime[i] - beta[i] * tempxys[i + 1][0] + 0.5);
  184.         tempxys[i]
  185.             [1] = (int32) floor(Yrprime[i] - beta[i] * tempxys[i + 1][1] + 0.5);
  186.     }
  187.  
  188.     if (isclosed)
  189.     {
  190.         /*
  191.          * at this point, we've probably been through one control-point adjustment, so let's not muck it up
  192.          */
  193.         tempxys[numpts + 1][0] = tempxys[1][0];
  194.         tempxys[numpts + 1][1] = tempxys[1][1];
  195.         tempxys[numpts + 2][0] = tempxys[2][0];
  196.         tempxys[numpts + 2][1] = tempxys[2][1];
  197.         tempxys[0][0] = tempxys[numpts][0];
  198.         tempxys[0][1] = tempxys[numpts][1];
  199.         /* copy them back */
  200.         for (i = 0; i <= numpts + 2; i++)
  201.         {
  202.             xys[i][0] = tempxys[i][0];
  203.             xys[i][1] = tempxys[i][1];
  204.         }
  205.         return;
  206.     }            /* closed */
  207.     /* copy back */
  208.     for (i = 2; i < numpts; i++)
  209.     {
  210.         xys[i][0] = tempxys[i][0];
  211.         xys[i][1] = tempxys[i][1];
  212.     }
  213.  
  214.     /* open */
  215. }
  216.  
  217.  
  218. /*-----------------------------------------------------*/
  219. /*
  220.  * adjust the list of control points so that we can use it for  B-spline interpolation. Add any "phantom" vertices necessary so
  221.  * that the end conditions will be correct for interpolation
  222.  */
  223. static void 
  224. Bctlptadjust(isclosed, isarc, n, xys, thx)
  225.     int        isclosed, isarc;
  226.     int32          *n;
  227. int32(*xys)[2];
  228.     VThickness     *thx;
  229. {                /* ctlpt adjust */
  230.     /* INOUT */
  231.     /* INOUT */
  232.     /* INOUT */
  233.     int32           j;
  234.     ControlPoints   tmp;
  235.     ThickAryType    tmpthx;
  236.     int32           FORLIM;
  237.  
  238.     if (isclosed)
  239.     {
  240.         if (*n == 2)
  241.         {
  242.             complain(ERRBAD);
  243.             fprintf(logfile,
  244.                 "A closed spline requires more than 2 control points \n");
  245.             fprintf(logfile, "making a temporary fix in order to continue...\n");
  246.             xys[3][0] = xys[1][0];
  247.             xys[3][1] = xys[1][1];
  248.         }
  249.  
  250.         FORLIM = *n;
  251.         for (j = 1; j <= FORLIM; j++)
  252.         {
  253.             tmp[j][0] = xys[j][0];
  254.             tmp[j][1] = xys[j][1];
  255.             tmpthx[j] = thx[j];
  256.         }
  257.         /* Now take care of the 'phantom' vertices */
  258.         tmp[*n + 1][0] = xys[1][0];
  259.         tmp[*n + 1][1] = xys[1][1];
  260.         tmpthx[*n + 1] = thx[1];
  261.         tmp[*n + 2][0] = xys[2][0];
  262.         tmp[*n + 2][1] = xys[2][1];
  263.         tmpthx[*n + 2] = thx[2];
  264.         tmp[*n + 3][0] = xys[3][0];
  265.         tmp[*n + 3][1] = xys[3][1];
  266.         tmpthx[*n + 3] = thx[3];
  267.  
  268.         if (!isarc)
  269.         {
  270.             tmp[0][0] = xys[*n][0];    /* wrap around to the real last point */
  271.             tmp[0][1] = xys[*n][1];
  272.             tmpthx[0] = thx[*n];
  273.         }
  274.         else
  275.         {
  276.             tmp[0][0] = xys[0][0];
  277.             tmp[0][1] = xys[0][1];
  278.             tmpthx[0] = thx[0];
  279.         }
  280.  
  281.         (*n)++;        /* we supplied the 'last' point for the user */
  282.  
  283.         FORLIM = *n + 2;
  284.         for (j = 0; j <= FORLIM; j++)
  285.         {
  286.             xys[j][0] = tmp[j][0];
  287.             xys[j][1] = tmp[j][1];
  288.             thx[j] = tmpthx[j];
  289.         }        /* for */
  290.         return;
  291.     }            /* if closed */
  292.     /*
  293.      * here, we have to supply the last 'real' point for the user, and add three phantoms-- one before, and two after
  294.      */
  295.  
  296.  
  297.     if (!isarc)
  298.     {
  299.         tmp[0][0] = xys[1][0] * 2 - xys[2][0];
  300.         tmp[0][1] = xys[1][1] * 2 - xys[2][1];
  301.     }
  302.     else
  303.     {
  304.         tmp[0][0] = xys[0][0];
  305.         tmp[0][1] = xys[0][1];
  306.     }
  307.     tmpthx[0] = thx[1];
  308.  
  309.     FORLIM = *n;
  310.     for (j = 1; j <= FORLIM; j++)
  311.     {
  312.         tmp[j][0] = xys[j][0];
  313.         tmp[j][1] = xys[j][1];
  314.         tmpthx[j] = thx[j];
  315.     }
  316.  
  317.     tmp[*n + 1][0] = xys[*n][0] * 2 - xys[*n - 1][0];
  318.     tmp[*n + 1][1] = xys[*n][1] * 2 - xys[*n - 1][1];
  319.     tmpthx[*n + 1] = thx[*n];
  320.  
  321.     tmp[*n + 2][0] = tmp[*n + 1][0];
  322.     tmp[*n + 2][1] = tmp[*n + 1][1];
  323.     tmpthx[*n + 2] = thx[*n];
  324.  
  325.     FORLIM = *n + 2;
  326.     for (j = 0; j <= FORLIM; j++)
  327.     {
  328.         xys[j][0] = tmp[j][0];
  329.         xys[j][1] = tmp[j][1];
  330.         thx[j] = tmpthx[j];
  331.     }            /* for */
  332.  
  333.     /* OPEN SPLINE */
  334.     /* if open */
  335. }
  336.  
  337.  
  338.  
  339. /*-----------------------------------------------------*/
  340. /*
  341.  * adjust the list of control points so that we can use it for simple Catmull-Rom spline interpolation. Add any "phantom"
  342.  * vertices necessary so that the end conditions will be correct for interpolation
  343.  */
  344. static void 
  345. CRctlptadjust(isclosed, isarc, n, xys, thx)
  346.     int        isclosed, isarc;
  347.     int32          *n;
  348. int32(*xys)[2];
  349.     VThickness     *thx;
  350. {                /* ctlpt adjust */
  351.     /* INOUT */
  352.     /* INOUT */
  353.     /* INOUT */
  354.     int32           j;
  355.     ControlPoints   tmp;
  356.     ThickAryType    tmpthx;
  357.     int32           FORLIM;
  358.  
  359.     if (isclosed)
  360.     {
  361.         if (*n == 2)
  362.         {
  363.             complain(ERRBAD);
  364.             fprintf(logfile,
  365.                 "A closed spline requires more than 2 control points \n");
  366.             fprintf(logfile, "making a temporary fix in order to continue...\n");
  367.             xys[3][0] = xys[1][0];
  368.             xys[3][1] = xys[1][1];
  369.         }
  370.  
  371.  
  372.         FORLIM = *n;
  373.         for (j = 1; j <= FORLIM; j++)
  374.         {
  375.             tmp[j][0] = xys[j][0];
  376.             tmp[j][1] = xys[j][1];
  377.             tmpthx[j] = thx[j];
  378.         }
  379.         /* the phantom vertices */
  380.         tmp[*n + 1][0] = xys[1][0];
  381.         tmp[*n + 1][1] = xys[1][1];
  382.         tmpthx[*n + 1] = thx[1];
  383.         tmp[*n + 2][0] = xys[2][0];
  384.         tmp[*n + 2][1] = xys[2][1];
  385.         tmpthx[*n + 2] = thx[2];
  386.         tmp[*n + 3][0] = xys[3][0];
  387.         tmp[*n + 3][1] = xys[3][1];
  388.         tmpthx[*n + 3] = thx[3];
  389.  
  390.         if (!isarc)
  391.         {
  392.             tmp[0][0] = xys[*n][0];    /* wrap around to the real last point */
  393.             tmp[0][1] = xys[*n][1];
  394.             tmpthx[0] = thx[*n];
  395.         }
  396.         else
  397.         {
  398.             tmp[0][0] = xys[0][0];
  399.             tmp[0][1] = xys[0][1];
  400.             tmpthx[0] = thx[0];
  401.         }
  402.         (*n)++;        /* we supplied the 'last' point for the user */
  403.  
  404.         FORLIM = *n + 2;
  405.         for (j = 0; j <= FORLIM; j++)
  406.         {
  407.             xys[j][0] = tmp[j][0];
  408.             xys[j][1] = tmp[j][1];
  409.             thx[j] = tmpthx[j];
  410.         }        /* for */
  411.         return;
  412.     }            /* if closed */
  413.     /*
  414.      * here, we have to supply the last 'real' point for the user, and add three phantoms-- one before, and two after
  415.      */
  416.  
  417.     if (!isarc)
  418.     {
  419.         tmp[0][0] = xys[1][0];    /* double the first point */
  420.         tmp[0][1] = xys[1][1];
  421.     }
  422.     else
  423.     {
  424.         tmp[0][0] = xys[0][0];
  425.         tmp[0][1] = xys[0][1];
  426.     }
  427.     tmpthx[0] = thx[1];
  428.  
  429.     FORLIM = *n;
  430.     for (j = 1; j <= FORLIM; j++)
  431.     {
  432.         tmp[j][0] = xys[j][0];
  433.         tmp[j][1] = xys[j][1];
  434.         tmpthx[j] = thx[j];
  435.     }
  436.  
  437.     tmp[*n + 1][0] = xys[*n][0];    /* and triple the last */
  438.     tmp[*n + 1][1] = xys[*n][1];
  439.     tmpthx[*n + 1] = thx[*n];
  440.     tmp[*n + 2][0] = xys[*n][0];
  441.     tmp[*n + 2][1] = xys[*n][1];
  442.     tmpthx[*n + 2] = thx[*n];
  443.  
  444.     FORLIM = *n + 2;
  445.     for (j = 0; j <= FORLIM; j++)
  446.     {
  447.         xys[j][0] = tmp[j][0];
  448.         xys[j][1] = tmp[j][1];
  449.         thx[j] = tmpthx[j];
  450.     }            /* for */
  451.  
  452.     /* OPEN SPLINE */
  453.     /* if open */
  454. }                /* ctlpt adjust */
  455.  
  456.  
  457.  
  458. /*----------------------------------------------------------*/
  459.  
  460. static void 
  461. interpsplines(splinetype, isclosed, isanArc, linepatt,
  462.           basismatrix, numctls, arrayXY, pointmatrix,
  463.           varythicks, thickmatrix, TTmatrix)
  464.     SplineKind      splinetype;
  465.     int        isclosed, isanArc;
  466.     LineStyle       linepatt;
  467.     double          (*basismatrix)[4];
  468.     int32           numctls;
  469. int32(*arrayXY)[2];
  470. int32(*pointmatrix)[2];
  471.     int        varythicks;
  472.     VThickness     *thickmatrix, *TTmatrix;
  473. {                /* interp splines */
  474.     /* IN */
  475.     /* IN */
  476.     /* OUT */
  477.     /* IN */
  478.     /* OUT */
  479.     double          xctl[4], yctl[4];    /* vectors of x, y posits of control points */
  480.     double          wctl[4];/* vector of thicknesses at each ctl pt */
  481.     double          t, incr;
  482.     int32           Pi;    /* P sub i */
  483.     int32           currpt;
  484.     ScaledPts       theresolution;
  485.  
  486.     if (!isclosed && isanArc)    /* lie a little */
  487.         numctls++;
  488.  
  489.     switch (splinetype)
  490.     {
  491.  
  492.     case BSPL:
  493.         Bctlptadjust(isclosed, isanArc, &numctls, arrayXY, thickmatrix);
  494.         break;
  495.  
  496.     case CARD:
  497.     case CATROM:
  498.         CRctlptadjust(isclosed, isanArc, &numctls, arrayXY, thickmatrix);
  499.         break;
  500.  
  501.     case INTBSPL:
  502.         if (isclosed)
  503.         {
  504.             Bctlptadjust(true, isanArc, &numctls, arrayXY, thickmatrix);
  505.             invertsplvertices(numctls, true, arrayXY);
  506.         }
  507.         else
  508.         {
  509.             invertsplvertices(numctls, false, arrayXY);
  510.             Bctlptadjust(false, isanArc, &numctls, arrayXY, thickmatrix);
  511.         }        /* else */
  512.         break;
  513.         /* Interpolating Bsplines */
  514.     }
  515.  
  516.     if (!isclosed && isanArc)    /* UN-lie a little */
  517.         numctls--;
  518.  
  519.  
  520.     /*
  521.      * this is the scheme: val :=  t-vector   *  Basis matrix     * point matrix [t^3  t^2 t 1] *      [[Ms]]       * [Pi-1
  522.      * Pi Pi+1 Pi+2] where "Pi-1" is "P sub (i-1)", etc.
  523.      * 
  524.      * But we do this in a round about way: Point matrix * basis then   * t-vector   will yield the single value
  525.      * 
  526.      * there are certainly faster ways to do this, but this is the easiest to understand
  527.      */
  528.  
  529.     currpt = 1;
  530.     switch (linepatt)
  531.     {
  532.  
  533.     case solid:
  534.         theresolution = MAXVECLENsp;
  535.         break;
  536.  
  537.     case dotted:
  538.     case dashed:
  539.     case dotdash:        /* ### */
  540.         theresolution = MAXVECLENsp * 3;
  541.         break;
  542.     }
  543.  
  544.     for (Pi = 1; Pi < numctls; Pi++)
  545.     {
  546.         xctl[0] = float_(arrayXY[Pi - 1][0]);
  547.         xctl[1] = float_(arrayXY[Pi][0]);
  548.         xctl[2] = float_(arrayXY[Pi + 1][0]);
  549.         xctl[3] = float_(arrayXY[Pi + 2][0]);
  550.         yctl[0] = float_(arrayXY[Pi - 1][1]);
  551.         yctl[1] = float_(arrayXY[Pi][1]);
  552.         yctl[2] = float_(arrayXY[Pi + 1][1]);
  553.         yctl[3] = float_(arrayXY[Pi + 2][1]);
  554.         matXvector(basismatrix, xctl, xctl);
  555.         matXvector(basismatrix, yctl, yctl);
  556.  
  557.         /*
  558.          * compute the delta-t increment for this segment based on a metric for subdivision
  559.          */
  560.         intervals = numsubdivisions(xctl, yctl, theresolution);
  561.         if (linepatt == solid && intervals <= 2)
  562.             intervals *= 2;
  563.         incr = 1.0 / intervals;
  564.  
  565.         /* avoid over-flowing the "pointmatrix" */
  566.         if (currpt + intervals - 1 >= MAXSPLINESEGS)
  567.         {
  568.             complain(ERRREALBAD);
  569.             fprintf(logfile, "error: Too many spline segments required.\n");
  570.             fprintf(logfile,
  571.                 " Reducing the number of control points to get output.\n");
  572.             goto _L32;
  573.         }
  574.  
  575.         t = 0.0;
  576.         while (t < 0.999999999)
  577.         {
  578.             pointmatrix[currpt - 1][0] = (int32) floor(splinePosition(xctl, t) + 0.5);
  579.             pointmatrix[currpt - 1][1] = (int32) floor(splinePosition(yctl, t) + 0.5);
  580.  
  581.             if (varythicks)
  582.             {
  583.                 wctl[0] = float_((int32) thickmatrix[Pi - 1]);
  584.                 wctl[1] = float_((int32) thickmatrix[Pi]);
  585.                 wctl[2] = float_((int32) thickmatrix[Pi + 1]);
  586.                 wctl[3] = float_((int32) thickmatrix[Pi + 2]);
  587.                 matXvector(catrommtx, wctl, wctl);    /* requires using Catmull-Rom */
  588.                 TTmatrix[currpt] = (int32) floor(splinePosition(wctl, t) + 0.5);
  589.             }
  590.  
  591.             t += incr;
  592.             currpt++;
  593.         }        /* while loop */
  594.  
  595.  
  596.     }            /* for loop */
  597.  
  598. _L32:
  599.     /* the END-condtion */
  600.     pointmatrix[currpt - 1][0] = (int32) floor(splinePosition(xctl, 1.0) + 0.5);
  601.     pointmatrix[currpt - 1][1] = (int32) floor(splinePosition(yctl, 1.0) + 0.5);
  602.     if (varythicks)
  603.     {
  604.         wctl[0] = thickmatrix[numctls - 2];
  605.         wctl[1] = thickmatrix[numctls - 1];
  606.         wctl[2] = thickmatrix[numctls];
  607.         wctl[3] = thickmatrix[numctls + 1];
  608.         matXvector(catrommtx, wctl, wctl);    /* requires using Catmull-Rom */
  609.         TTmatrix[currpt] = (int32) floor(splinePosition(wctl, 1.0) + 0.5);
  610.     }
  611.  
  612.     lastPoint = currpt;
  613.  
  614. }                /* interpsplines */
  615.  
  616.  
  617. /*----------------------------------------------------------------*/
  618. void 
  619. drawSpline(splinetype, isclosed, isanArc, patt, numctls, arrayXY,
  620.        pointmatrix, varythicks, thickmatrix, TTmatrix)
  621.     SplineKind      splinetype;
  622.     int        isclosed, isanArc;
  623.     LineStyle       patt;
  624.     int32           numctls;
  625. int32(*arrayXY)[2];
  626. int32(*pointmatrix)[2];
  627.     int        varythicks;
  628.     VThickness     *thickmatrix, *TTmatrix;
  629. {
  630.     /* IN */
  631.     /* OUT */
  632.     /* IN */
  633.     /* OUT */
  634.     lastPoint = 0;
  635.  
  636.  
  637.     switch (splinetype)
  638.     {
  639.  
  640.     case CATROM:
  641.         interpsplines(splinetype, isclosed, isanArc, patt, catrommtx, numctls,
  642.                   arrayXY, pointmatrix, varythicks, thickmatrix, TTmatrix);
  643.         break;
  644.  
  645.     case CARD:
  646.         interpsplines(splinetype, isclosed, isanArc, patt, cardmtx, numctls,
  647.                   arrayXY, pointmatrix, varythicks, thickmatrix, TTmatrix);
  648.         break;
  649.  
  650.     case BSPL:
  651.         interpsplines(splinetype, isclosed, isanArc, patt, bsplmtx, numctls,
  652.                   arrayXY, pointmatrix, varythicks, thickmatrix, TTmatrix);
  653.         break;
  654.  
  655.     case INTBSPL:
  656.         interpsplines(splinetype, isclosed, isanArc, patt, bsplmtx, numctls,
  657.                   arrayXY, pointmatrix, varythicks, thickmatrix, TTmatrix);
  658.         break;
  659.     }            /* Case */
  660. }
  661.